﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Neo4j.Driver;
using Neo4jClient.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WinFormsApp1.DesignForms;
using WinFormsApp1.Properties;

namespace WinFormsApp1
{
    public partial class DesignKNMapForm : UserControl
    {
        private KnowlgeMap m_map;
        public DesignKNMapForm()
        {
            InitializeComponent();
        }
        private void DesignKNMapForm_Load(object sender, EventArgs e)
        {
            m_map = new KnowlgeMap();
            m_map.Initialize();
        }

        #region 1-1 新增实体
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            var selGroup = "";
            TreeNode selGroupTreeNode = null;
            if (this.treeView1.SelectedNode != null)
            {
                var tn = this.treeView1.SelectedNode;
                while (tn != null && tn.Tag is CommonEntity)
                {
                    tn = tn.Parent;
                }
                if (tn != null)
                {
                    selGroupTreeNode = tn;
                    selGroup = tn.FullPath;
                }
            }
            CreateEntityForm form = new CreateEntityForm();
            form.StartPosition = FormStartPosition.CenterScreen;
            form.SelectMap = m_map;
            form.SelectGroup = selGroup;
            if (form.ShowDialog() == DialogResult.OK)
            {
                TreeNode tn = new TreeNode()
                {
                    Text = form.CreatedEntity.GetName(),
                    ImageIndex = 1,
                    SelectedImageIndex = 1
                };
                tn.Tag = form.CreatedEntity;
                if (selGroupTreeNode != null) { selGroupTreeNode.Nodes.Add(tn); }
                else { this.treeView1.Nodes.Add(tn); }
                m_map.AddEntity(form.CreatedEntity);

                if (m_realStore)
                {
                    m_readNeo4jStore.SaveEntity(form.CreatedEntity.ToSimpleTaskEntity());
                }
            }
        }
        private void 新建实体ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButton1_Click(null, null);
        }
        private void 更改ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null)
            {
                return;
            }
            var selEntity = this.treeView1.SelectedNode.Tag as CommonEntity;
            if (selEntity == null)
            {
                GroupForm form = new GroupForm();
                form.StartPosition = FormStartPosition.CenterScreen;
                form.GroupName = this.treeView1.SelectedNode.Text;
                if (form.ShowDialog() == DialogResult.OK)
                {
                    this.treeView1.SelectedNode.Text = form.GroupName;
                }
            }
            else
            {
                CreateEntityForm form = new CreateEntityForm();
                form.StartPosition = FormStartPosition.CenterScreen;
                form.CreatedEntity = selEntity;
                form.SelectMap = m_map;
                if (form.ShowDialog() == DialogResult.OK)
                {
                    this.treeView1.SelectedNode.Text = form.CreatedEntity.GetName();
                }
            }
        }
        #endregion

        #region 分组
        private void 新建分组ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            GroupForm form = new GroupForm();
            form.StartPosition = FormStartPosition.CenterScreen;
            if (form.ShowDialog() == DialogResult.OK)
            {
                TreeNode selNode = this.treeView1.SelectedNode;
                TreeNode tn = new TreeNode()
                {
                    Text = form.GroupName,
                    SelectedImageIndex = 0,
                    ImageIndex = 0,
                };
                if ((selNode.Tag is CommonEntity) == false)
                {
                    if (MessageBox.Show("是否置于" + selNode.Text + "之下?", "目录", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        selNode.Nodes.Add(tn);
                    }
                    else
                    {
                        this.treeView1.Nodes.Add(tn);
                    }
                }
                else
                {
                    this.treeView1.Nodes.Add(tn);
                }
            }
        }
        private TreeNode m_selGroupNode;
        private void 复制组名称ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode selNode = this.treeView1.SelectedNode;
            if (selNode == null) { return; }
            if (selNode.Tag is CommonEntity) return;
            var fullPath = selNode.FullPath;
            Clipboard.SetText(fullPath);
            m_selGroupNode = selNode;
        }

        private void 应用组ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode selNode = this.treeView1.SelectedNode;
            if (selNode == null) { return; }
            CommonEntity selItem = selNode.Tag as CommonEntity;
            if (selItem == null) return;
            selItem.SetGroup(Clipboard.GetText());
            selNode.Remove();
            m_selGroupNode.Nodes.Add(selNode);
        }
        #endregion

        #region 2-1 存储
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(m_lastIndexFileName))
            {
                toolStripButton2_Click(null, null);
            }
            var str = JsonConvert.SerializeObject(m_map);

            File.WriteAllText(m_lastIndexFileName, str);
        }
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "*.json|*.json";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                var str = JsonConvert.SerializeObject(m_map);

                File.WriteAllText(saveFileDialog.FileName, str);
            }
        }
        #endregion

        #region 3-1 从文件加载
        private string m_lastIndexFileName;
        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            OpenFileDialog saveFileDialog = new OpenFileDialog();
            saveFileDialog.Filter = "*.json|*.json";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                m_lastIndexFileName = saveFileDialog.FileName;
                
                m_map = KnowlgeMap.FromFile(saveFileDialog.FileName); 
                m_map.BuildIndex();
                BuildTree();
            }
        }
        private void BuildTree()
        {
            Dictionary<string, TreeNode> kNodes = CreateGroupTreeNodes();
            var nodes = m_map.GetNodes();
            for (var i = 0; i < nodes.Count; i++)
            {
                TreeNode tn = new TreeNode()
                {
                    Text = nodes[i].labels[0],
                    ImageIndex = 1,
                    SelectedImageIndex = 1
                };
                tn.Tag = nodes[i];
                var group = nodes[i].GetGroup();
                if (group != null)
                {
                    kNodes[group].Nodes.Add(tn);
                }
                else
                {
                    this.treeView1.Nodes.Add(tn);
                }
            }
            var relations = m_map.GetRelationships();
            List<string> relationTypes = new List<string>();
            for (var i = 0; i < relations.Count; i++)
            {
                var s1 = m_map.GetNodeById(relations[i].startNode);
                var s2 = m_map.GetNodeById(relations[i].endNode);
                TreeNode tn = new TreeNode()
                {
                    Text = s1.GetName() + "-" + relations[i].type + "-" + s2.GetName()
                };
                tn.Tag = relations[i];
                this.treeView2.Nodes.Add(tn);

                relationTypes.Add(relations[i].type); ;
            }
            this.comboBox1.Items.AddRange(relationTypes.Distinct().ToArray());
        }
        private Dictionary<string, TreeNode> CreateGroupTreeNodes()
        {
            var groups = m_map.GetGroups();
            Dictionary<string, TreeNode> kNodes = new Dictionary<string, TreeNode>();
            for (var i = 0; i < groups.Count; i++)
            {
                var paths = groups[i].Split('\\');
                TreeNode parentNode = null;
                var fullPath = "";
                for (var j = 0; j < paths.Length; j++)
                {
                    if (j == 0)
                    {
                        fullPath = paths[j];
                    }
                    else
                    {
                        fullPath = fullPath + "\\" + paths[j];
                    }
                    if (kNodes.ContainsKey(fullPath))
                    {
                        parentNode = kNodes[fullPath];
                        continue;
                    }
                    var treeNode = new TreeNode()
                    {
                        Text = paths[j]
                    };
                    kNodes.Add(fullPath, treeNode);
                    if (parentNode == null)
                    {
                        treeView1.Nodes.Add(treeNode);
                    }
                    else
                    {
                        parentNode.Nodes.Add(treeNode);
                    }
                    parentNode = treeNode;
                }
            }
            return kNodes;
        }
        #endregion

        #region 3-2 从数据库打开
        private void toolStripButtonOpenDB_Click(object sender, EventArgs e)
        {
            var m_client = new Neo4JServe();
            m_client.Initialize();
            m_map = KnowlgeMap.FromDB<SimpleTaskEntity, CommonRelation>(m_client.Client, "SimpleTaskEntity");
            m_map.BuildIndex();
            m_client.Dispose();

            BuildTree();
        }
        #endregion

        #region 4-1 添加关系
        private CommonEntity m_selectEntity1;
        private List<CommonEntity> m_selectChildrenEntityItems = new List<CommonEntity>();

        private void 设置为ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_selectEntity1 = this.treeView1.SelectedNode.Tag as CommonEntity;
            if (m_selectEntity1 == null)
            {
                this.textBox1.Text = "";
            }
            else
            {
                this.textBox1.Text = m_selectEntity1.GetName();
            }
        }
        private void 设为子关系节点ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var m_selectEntity2 = this.treeView1.SelectedNode.Tag as CommonEntity;
            if (m_selectEntity2 == null)
            {
                return;
            }
            else
            {
                this.listBox1.Items.Add(m_selectEntity2.GetName());
                m_selectChildrenEntityItems.Add(m_selectEntity2);
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            var relationType = this.comboBox1.Text;
            foreach (var m_selectEntity2 in m_selectChildrenEntityItems)
            {
                var r = m_map.AddRelation(m_selectEntity1, m_selectEntity2, relationType);
                r.startNodeType = "SimpleTaskEntity";
                r.endNodeType = "SimpleTaskEntity";

                TreeNode tn2 = new TreeNode(m_selectEntity1.GetName() + "-" + relationType + "-" + m_selectEntity2.GetName());
                tn2.Tag = r;
                this.treeView2.Nodes.Add(tn2);

                if (m_realStore)
                {
                    m_readNeo4jStore.SaveRelation(r);
                }
            }
            if (this.comboBox1.Items.Contains(relationType) == false)
            {
                this.comboBox1.Items.Insert(0, relationType);
            }
        }
        private void 清除关系记录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            m_selectChildrenEntityItems.Clear();
        }
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            清除关系记录ToolStripMenuItem_Click(null, null);
        }
        #endregion

        #region 4-2 删除管线
        private void 删除管线ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var tn = this.treeView2.SelectedNode;
            if (tn != null)
            {
                if (MessageBox.Show("是否删除管线" + tn.Text, "删除关系", MessageBoxButtons.OKCancel) == DialogResult.OK)
                {
                    m_map.DeleteRelation(tn.Tag as CommonRelation);
                    tn.Remove();
                }
            }
        }

        private void 更改关系ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var tn = this.treeView2.SelectedNode;
            if (tn != null)
            {
                GroupForm form = new GroupForm();
                form.StartPosition = FormStartPosition.CenterScreen;
                var selCommonRelation = tn.Tag as CommonRelation;
                form.GroupName = (tn.Tag as CommonRelation).type;
                form.Text = "更新关系名称";
                if (form.ShowDialog() == DialogResult.OK)
                {
                    selCommonRelation.type = form.GroupName;
                    tn.Text = selCommonRelation.ToFormatString(m_map);
                }
            }
        }
        #endregion

        #region 4-3 指引关系
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            ReleaseHideNodes();
            var nodes = this.treeView2.Nodes;
            for (var i = 0; i < nodes.Count; i++)
            {
                var node = nodes[i];
                node.BackColor = Color.Empty;
            }
            var selEntity = this.treeView1.SelectedNode.Tag as CommonEntity;
            if (selEntity == null) { return; }
            for (var i = 0; i < nodes.Count; i++)
            {
                var cr = nodes[i].Tag as CommonRelation;
                if (cr.startNode == selEntity.id)
                {
                    nodes[i].BackColor = Color.LightCoral;
                }
                if (cr.endNode == selEntity.id)
                {
                    nodes[i].BackColor = Color.LightGreen;
                }
            }
            checkBox1_CheckedChanged(null, null);
        }
        #endregion

        #region 4-4 过滤管线
        private List<TreeNode> m_hideTreeNodes = new List<TreeNode>();
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (this.checkBox1.Checked)
            {
                var nodes = this.treeView2.Nodes;
                for (var i = nodes.Count - 1; i >= 0; i--)
                {
                    var node = nodes[i];
                    if (node.BackColor == Color.Empty)
                    {
                        m_hideTreeNodes.Add(node);
                        node.Remove();
                    }
                }
            }
            else
            {
                ReleaseHideNodes();
            }
        }
        private void ReleaseHideNodes()
        {
            for (var i = 0; i < m_hideTreeNodes.Count; i++)
            {
                this.treeView2.Nodes.Add(m_hideTreeNodes[i]);
            }
            m_hideTreeNodes.Clear();
        }
        #endregion

        #region 5-1 上传Neo4j
        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            KnowlgeMapToNeo4j< SimpleTaskEntity> knowlgeMapToNeo4J = new KnowlgeMapToNeo4j<SimpleTaskEntity>();
            knowlgeMapToNeo4J.Initialize();
            var nodes = m_map.GetNodes();
            var taskNode = new List<SimpleTaskEntity>();
            for (var i = 0; i < nodes.Count; i++)
            {
                taskNode.Add(nodes[i].ToSimpleTaskEntity());
            }
            knowlgeMapToNeo4J.AddTaskEntityAsync(taskNode);
            var r = m_map.GetRelationships();
            for (var i = 0; i < r.Count; i++)
            {
                var relation = r[i];
                relation.startNodeType = "SimpleTaskEntity";
                relation.endNodeType = "SimpleTaskEntity";
                knowlgeMapToNeo4J.SaveRelation(relation);
            }
            MessageBox.Show("成功");
        }
        #endregion

        #region 5-2 实时存储Neo4J
        private bool m_realStore = false;
        private KnowlgeMapToNeo4j<SimpleTaskEntity> m_readNeo4jStore;
        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            m_realStore = !m_realStore;
            if (m_realStore)
            {
                MessageBox.Show("已经开启实时存储Neo4J的功能");
                toolStripButton6.Image = Resources.page_red;
            }
            else
            {
                MessageBox.Show("已经关闭实时存储Neo4J的功能");
                toolStripButton6.Image = Resources.page_white;
            }
            if (m_realStore)
            {
                m_readNeo4jStore = new KnowlgeMapToNeo4j<SimpleTaskEntity>();
                m_readNeo4jStore.Initialize();
            }
            else if (m_readNeo4jStore != null)
            {
                m_readNeo4jStore.Dispose();
            }
        }
        #endregion

        
    }
}
